home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 5 / MACVOGL- / OBJECTS.C < prev    next >
C/C++ Source or Header  |  1992-07-19  |  8KB  |  453 lines

  1. #include <stdio.h>
  2.  
  3. #include "vogl.h"
  4.  
  5. extern void        polyobj();
  6.  
  7. typedef struct o {
  8.     int        obno;
  9.     TokList        *tlist;
  10.     struct o    *next;
  11. } VObject;
  12.  
  13. static VObject        *object_table[MAXENTS];
  14.  
  15. static long        obno = -1, omax = 0;
  16.  
  17. /*
  18.  * makeobj
  19.  *
  20.  *    start a new object.
  21.  *
  22.  */
  23. void
  24. makeobj(ob)
  25.     long    ob;
  26. {
  27.     VObject    *o;
  28.     int    n = ob;
  29.  
  30.     if (!vdevice.initialised)
  31.         verror("makeobj: vogl not initialised");
  32.  
  33.     for (o = object_table[n % MAXENTS]; o != (VObject *)NULL; o = o->next)
  34.         if (o->obno == n) {
  35.             delobj((long)n);
  36.             break;
  37.         }
  38.  
  39.     obno = n;
  40.     vdevice.tokens = (TokList *)NULL;
  41.  
  42.     vdevice.inobject = 1;
  43.  
  44.     if (omax <= n)
  45.         omax = n + 1;
  46. }
  47.  
  48. /*
  49.  * closeobj
  50.  *
  51.  *    close an object
  52.  */
  53. void
  54. closeobj()
  55. {
  56.     VObject    *o;
  57.  
  58.     if (!vdevice.inobject)
  59.         verror("closeobj: not in an object");
  60.  
  61.     vdevice.inobject = 0;
  62.  
  63.     o = (VObject *)vallocate(sizeof(VObject));
  64.     o->obno = obno;
  65.     o->tlist = vdevice.tokens;
  66.     o->next = object_table[obno % MAXENTS];
  67.  
  68.     object_table[obno % MAXENTS] = o;
  69.  
  70.     obno = -1;
  71. }
  72.  
  73. /*
  74.  * delobj
  75.  *
  76.  *    deletes an object, freeing its memory
  77.  */
  78. void
  79. delobj(ob)
  80.     long    ob;
  81. {
  82.     VObject    *o, *lo;
  83.     TokList    *tl, *ntl;
  84.     int    n = ob;
  85.  
  86.     for (lo = o = object_table[n % MAXENTS]; o != (VObject *)NULL; lo = o, o = o->next)
  87.         if (o->obno == n)
  88.             break;
  89.  
  90.     if (o != (VObject *)NULL) {
  91.         for (tl = o->tlist; tl != (TokList *)NULL; tl = ntl) {
  92.             ntl = tl->next;
  93.             if (tl->toks)
  94.                 free(tl->toks);
  95.  
  96.             free(tl);
  97.         }
  98.         if (lo == object_table[n % MAXENTS])
  99.             object_table[n % MAXENTS] = (VObject *)NULL;
  100.         else
  101.             lo->next = o->next;
  102.         free(o);
  103.     }
  104. }
  105.  
  106. /*
  107.  * genobj
  108.  *
  109.  *    generates a unique object identifier
  110.  */
  111. long
  112. genobj()
  113. {
  114.     return((long)omax++);
  115. }
  116.  
  117. /*
  118.  * getopenobj
  119.  *
  120.  *    returns the object currently being edited, -1 if none.
  121.  */
  122. long
  123. getopenobj()
  124. {
  125.     return((long)obno);
  126. }
  127.  
  128. /*
  129.  * doarc
  130.  *
  131.  *    draw an arc or circle.
  132.  */
  133. static void
  134. doarc(x, y, xoff, yoff, cosine, sine, nsegs)
  135.     double    x, y, xoff, yoff, cosine, sine;
  136.     int    nsegs;
  137. {
  138.     double    cx, cy, dx, dy;
  139.     int    i;
  140.  
  141.     cx = x + xoff;
  142.     cy = y + yoff;
  143.     move2(cx, cy);
  144.  
  145.     for (i = 0; i < nsegs; i++)  {
  146.         dx = cx - x;
  147.         dy = cy - y;
  148.         cx = x + dx * cosine - dy * sine;
  149.         cy = y + dx * sine + dy * cosine;
  150.         draw2(cx, cy);
  151.     }
  152. }
  153.  
  154. /*
  155.  * doarcf
  156.  *
  157.  *    draw a filled arc or circle.
  158.  */
  159. static void
  160. doarcf(x, y, xoff, yoff, cosine, sine, nsegs)
  161.     double    x, y, xoff, yoff, cosine, sine;
  162.     int    nsegs;
  163. {
  164.     double    cx, cy, dx, dy;
  165.     int    i;
  166.  
  167.     cx = x + xoff;
  168.     cy = y + yoff;
  169.     pmv2(cx, cy);
  170.  
  171.     for (i = 0; i < nsegs; i++)  {
  172.         dx = cx - x;
  173.         dy = cy - y;
  174.         cx = x + dx * cosine - dy * sine;
  175.         cy = y + dx * sine + dy * cosine;
  176.         pdr2(cx, cy);
  177.     }
  178.  
  179.     pclos();
  180. }
  181.  
  182. /*
  183.  * callobj
  184.  *
  185.  *    draws an object
  186.  */
  187. void
  188. callobj(ob)
  189.     long    ob;
  190. {
  191.     int    n = ob;
  192.     char    buf[BUFSIZ];
  193.  
  194.     VObject        *o;
  195.     TokList        *tl;
  196.     Matrix        prod, tmpmat;
  197.     Tensor        S;
  198.     int        i, j;
  199.     double        cx, cy, cz, *m;
  200.     register Token    *t, *et, *pt;
  201.  
  202.     if (!vdevice.initialised)
  203.         verror("callobj: vogl not initialised");
  204.  
  205.     if (vdevice.inobject) {
  206.         t = newtokens(2);
  207.  
  208.         t[0].i = CALLOBJ;
  209.         t[1].i = n;
  210.  
  211.         return;
  212.     }
  213.  
  214.     for (o = object_table[n % MAXENTS]; o != (VObject *)NULL; o = o->next)
  215.         if (o->obno == n)
  216.             break;
  217.  
  218.     if (o == (VObject *)NULL)
  219.         return;
  220.  
  221.     for (tl = o->tlist; tl != (TokList *)NULL; tl = tl->next) {
  222.         t = tl->toks;
  223.         et = &tl->toks[tl->count];
  224.         while (t != et) {
  225.             switch (t->i) {
  226.             case ARC:
  227.                 doarc(t[1].f, t[2].f, t[3].f, t[4].f, t[5].f, t[6].f, t[7].i);
  228.                 t += 8;
  229.                 break;
  230.             case ARCF:
  231.                 doarcf(t[1].f, t[2].f, t[3].f, t[4].f, t[5].f, t[6].f, t[7].i);
  232.                 t += 8;
  233.                 break;
  234.             case BACKBUFFER:
  235.                 backbuffer(t[1].i);
  236.                 t += 2;
  237.                 break;
  238.             case FRONTBUFFER:
  239.                 frontbuffer(t[1].i);
  240.                 t += 2;
  241.                 break;
  242.             case SWAPBUFFERS:
  243.                 swapbuffers();
  244.                 t += 1;
  245.                 break;
  246.             case BACKFACING:
  247.                 backface(t[1].i);
  248.                 t += 2;
  249.                 break;
  250.             case CALLOBJ:
  251.                 callobj(t[1].i);
  252.                 t += 2;
  253.                 break;
  254.             case CIRCLE:
  255.                 doarc(t[1].f, t[2].f, t[3].f, 0.0, t[4].f, t[5].f, t[6].i);
  256.                 draw2(t[1].f + t[3].f, t[2].f);
  257.                 t += 7;
  258.                 break;
  259.             case CIRCF:
  260.                 doarcf(t[1].f, t[2].f, t[3].f, 0.0, t[4].f, t[5].f, t[6].i);
  261.                 t += 7;
  262.                 break;
  263.             case RECTF:
  264.                 pmv2(t[1].f, t[2].f);
  265.                 pdr2(t[3].f, t[2].f);
  266.                 pdr2(t[3].f, t[4].f);
  267.                 pdr2(t[1].f, t[4].f);
  268.                 pdr2(t[1].f, t[2].f);
  269.                 pclos();
  270.                 t += 5;
  271.                 break;
  272.             case CLEAR:
  273.                 (*vdevice.dev.Vclear)();
  274.                 t++;
  275.                 break;
  276.             case COLOR:
  277.                 color(t[1].i);
  278.                 t += 2;
  279.                 break;
  280.             case DRAW:
  281.                 draw(t[1].f, t[2].f, t[3].f);
  282.                 t += 4;
  283.                 break;
  284.             case DRAWSTR:
  285.                 charstr(&t[1]);
  286.                 t += 2 + strlen(&t[1]) / sizeof(Token);
  287.                 break;
  288.             case FONT:
  289.                 font(t[1].i);
  290.                 t += 2;
  291.                 break;
  292.             case LOADMATRIX:
  293.                 m = (double *)vdevice.transmat->m;
  294.                 for (i = 0; i < 16; i++)
  295.                     *m++ = (++t)->f;
  296.  
  297.                 vdevice.cpVvalid = 0;           /* may have changed mapping from world to device coords */
  298.                 t++;
  299.  
  300.                 break;
  301.             case MAPCOLOR:
  302.                 mapcolor(t[1].i, t[2].i, t[3].i, t[4].i);
  303.                 t += 5;
  304.                 break;
  305.             case MOVE:
  306.                 move(t[1].f, t[2].f, t[3].f);
  307.                 t += 4;
  308.                 break;
  309.             case MULTMATRIX:
  310.                 m = (double *)tmpmat;
  311.                 for (i = 0; i < 16; i++)
  312.                     *m++ = (++t)->f;
  313.  
  314.                 mult4x4(prod, tmpmat, vdevice.transmat->m);
  315.                 loadmatrix(prod);
  316.                 t++;
  317.                 break;
  318.             case POLY:
  319.                 polyobj(t[1].i, &t[2], 0);
  320.                 t += 2 + 3 * t[1].i;
  321.                 break;
  322.             case POLYF:
  323.                 polyobj(t[1].i, &t[2], 1);
  324.                 t += 2 + 3 * t[1].i;
  325.                 break;
  326.             case CMOV:
  327.                 cmov(t[1].f, t[2].f, t[3].f);
  328.                 t += 4;
  329.                 break;
  330.             case POPATTRIBUTES:
  331.                 popattributes();
  332.                 t++;
  333.                 break;
  334.             case POPMATRIX:
  335.                 popmatrix();
  336.                 t++;
  337.                 break;
  338.             case POPVIEWPORT:
  339.                 popviewport();
  340.                 t++;
  341.                 break;
  342.             case PUSHATTRIBUTES:
  343.                 pushattributes();
  344.                 t++;
  345.                 break;
  346.             case PUSHMATRIX:
  347.                 pushmatrix();
  348.                 t++;
  349.                 break;
  350.             case PUSHVIEWPORT:
  351.                 pushviewport();
  352.                 t++;
  353.                 break;
  354.             case RCURVE:
  355.                 i = (++t)->i;
  356.                 cx = (++t)->f;
  357.                 cy = (++t)->f;
  358.                 cz = (++t)->f;
  359.                 m = (double *)tmpmat;
  360.                 for (j = 0; j < 16; j++)
  361.                     *m++ = (++t)->f;
  362.                 mult4x4(prod, tmpmat, vdevice.transmat->m);
  363.                 drcurve(i, prod);
  364.                 vdevice.cpW[V_X] = cx;
  365.                 vdevice.cpW[V_Y] = cy;
  366.                 vdevice.cpW[V_Z] = cz;
  367.                 t++;
  368.                 break;
  369.             case RPATCH:
  370.                 pt = t + 10;
  371.                 cx = (++t)->f;
  372.                 cy = (++t)->f;
  373.                 cz = (++t)->f;
  374.                 for (i = 0; i < 4; i++)
  375.                     for (j = 0; j < 4; j++) {
  376.                         S[0][i][j] = (pt++)->f;
  377.                         S[1][i][j] = (pt++)->f;
  378.                         S[2][i][j] = (pt++)->f;
  379.                         S[3][i][j] = (pt++)->f;
  380.                     }
  381.  
  382.                 transformtensor(S, vdevice.transmat->m);
  383.                 drpatch(S, t[1].i, t[2].i, t[3].i, t[4].i, t[5].i, t[6].i);
  384.  
  385.                 vdevice.cpW[V_X] = cx;
  386.                 vdevice.cpW[V_Y] = cy;
  387.                 vdevice.cpW[V_Z] = cz;
  388.                 t = pt;
  389.                 break;
  390.             case VIEWPORT:
  391.                 viewport(t[1].i, t[2].i, t[3].i, t[4].i);
  392.                 t += 5;
  393.                 break;
  394.             case TRANSLATE:
  395.                 translate(t[1].f, t[2].f, t[3].f);
  396.                 t += 4;
  397.                 break;
  398.             case SCALE:
  399.                 /*
  400.                  * Do the operations directly on the top matrix of
  401.                  * the stack to speed things up.
  402.                  */
  403.  
  404.                 vdevice.transmat->m[0][0] *= t[1].f;
  405.                 vdevice.transmat->m[0][1] *= t[1].f;
  406.                 vdevice.transmat->m[0][2] *= t[1].f;
  407.                 vdevice.transmat->m[0][3] *= t[1].f;
  408.  
  409.                 vdevice.transmat->m[1][0] *= t[2].f;
  410.                 vdevice.transmat->m[1][1] *= t[2].f;
  411.                 vdevice.transmat->m[1][2] *= t[2].f;
  412.                 vdevice.transmat->m[1][3] *= t[2].f;
  413.  
  414.                 vdevice.transmat->m[2][0] *= t[3].f;
  415.                 vdevice.transmat->m[2][1] *= t[3].f;
  416.                 vdevice.transmat->m[2][2] *= t[3].f;
  417.                 vdevice.transmat->m[2][3] *= t[3].f;
  418.  
  419.                 t += 4;
  420.                 break;
  421.             case ROTATE:
  422.                 rot(t[1].f, (char)t[2].i);
  423.                 t += 3;
  424.                 break;
  425.             default:
  426.                 sprintf(buf, "vogl: internal error in callobj (Token type %d used)", t->i);
  427.                 verror(buf);
  428.                 exit(1);
  429.             }
  430.         }
  431.     }
  432. }
  433.  
  434. /*
  435.  * isobj
  436.  *
  437.  *    returns 1 if there is an object n, 0 otherwise.
  438.  */
  439. Boolean
  440. isobj(ob)
  441.     long    ob;
  442. {
  443.     long    n = ob;
  444.  
  445.     VObject    *o;
  446.  
  447.     for (o = object_table[n % MAXENTS]; o != (VObject *)NULL; o = o->next)
  448.         if (o->obno == n)
  449.             break;
  450.  
  451.     return(o != (VObject *)NULL);
  452. }
  453.